/*******************************************************************************
 * Copyright 2011-2012 Dik Grapendaal
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package sh.grapendaal.tsuushin.module;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import sh.grapendaal.tsuushin.service.PermissionService;
import sh.grapendaal.tsuushin.tracking.User;

public class PermissionServiceModuleProxy implements ServiceModuleProxy, PermissionService {
	private PermissionService permissionService;

	private Set<String> permissions = new HashSet<String>();
	private List<User> users = new ArrayList<User>();
	
	public void setPermissionService(PermissionService permissionService) {
		this.permissionService = permissionService;
	}

	@Override
	public boolean registerPermission(String permission) {
		return permissionService.registerPermission(permission) && permissions.add(permission);
	}

	@Override
	public boolean unregisterPermission(String permission) {
		if (!this.isOwnPermission(permission)) {
			throw new IllegalArgumentException("Permission \"" + permission + "\" is not a permission"
					+ " registered by this module.");
		}
		return permissionService.unregisterPermission(permission);
	}

	@Override
	public boolean permissionExists(String permission) {
		return permissionService.permissionExists(permission);
	}

	@Override
	public List<String> getUsablePermissions() {
		return new ArrayList<String>(permissions);
	}

	@Override
	public void addUser(User user) {
		this.addUser(user, null);
	}

	@Override
	public void addUser(User user, String hashedPassword) {
		permissionService.addUser(user, hashedPassword);
		users.add(user);
	}

	@Override
	public void removeUser(User user) {
		if (!users.contains(user)) {
			throw new IllegalArgumentException("User " + user + " is not a user registered by this module.");
		}

		permissionService.removeUser(user);
	}

	@Override
	public boolean isUserKnown(User user) {
		return permissionService.isUserKnown(user);
	}

	@Override
	public boolean grantPermission(User user, String permission) {
		if (!this.isUserKnown(user)) {
			throw new IllegalArgumentException("User " + user + " not known in Permission Service.");
		}
		if (!this.permissionExists(permission)) {
			throw new IllegalArgumentException("Permission \"" + permission
					+ "\" not registered in Permission Service.");
		}
		if (!this.isOwnPermission(permission)) {
			throw new IllegalArgumentException("Permission \"" + permission + "\" is not a permission"
					+ " registered by this module.");
		}
		return permissionService.grantPermission(user, permission);
	}

	@Override
	public boolean revokePermission(User user, String permission) {
		if (!this.isUserKnown(user)) {
			throw new IllegalArgumentException("User " + user + " not known in Permission Service.");
		}
		if (!this.permissionExists(permission)) {
			throw new IllegalArgumentException("Permission \"" + permission
					+ "\" not registered in Permission Service.");
		}
		if (!this.isOwnPermission(permission)) {
			throw new IllegalArgumentException("Permission \"" + permission + "\" is not a permission"
					+ " registered by this module.");
		}
		return permissionService.revokePermission(user, permission);
	}

	@Override
	public boolean hasPermission(User user, String permission) {
		return permissionService.hasPermission(user, permission);
	}

	@Override
	public boolean isBotOwner(User user) {
		return permissionService.isBotOwner(user);
	}

	/**
	 * Checks whether the given permission belongs to the module this proxy is
	 * for.
	 * 
	 * @param permission
	 *            The permission to check.
	 * @return True when the permission is ours.
	 */
	private boolean isOwnPermission(String permission) {
		return permissions.contains(permission);
	}
}
